package org.hsieh.tr.explore.ui;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.custom.CTabItem;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.hsieh.tr.explore.exception.ExceptionHandler;

public class ResultView extends Composite implements ISqlResultView {

	private static final int MAX_LINES = 100;

	private static final String NEW_LINE = "\n";

	private CTabFolder folder;

	public ResultView(Composite parent, int style) {
		super(parent, style);
		createControls();
	}

	private void createControls() {
		GridLayoutFactory.swtDefaults().numColumns(1).margins(0, 0).applyTo(
				this);

		folder = new CTabFolder(this, SWT.TOP | SWT.CLOSE);
		GridDataFactory.fillDefaults().grab(true, true).applyTo(folder);

		MenuManager manager = new MenuManager("PopupMenu#");
		manager.add(new Action() {
			{
				setText("Close all");
			}

			@Override
			public void run() {
				CTabItem[] items = folder.getItems();
				if (items != null && items.length > 0) {
					for (CTabItem item : items) {
						item.dispose();
					}
				}
			}

		});
		Menu menu = manager.createContextMenu(folder);
		folder.setMenu(menu);

		GridLayoutFactory.swtDefaults().numColumns(1).margins(0, 0).applyTo(
				folder);
	}

	public void showResult(Object object) {
		CTabItem resultItem = null;
		if (object instanceof ResultSet) {
			resultItem = showResultSet((ResultSet) object);
		} else if (object instanceof Integer) {
			resultItem = createLabelTabItem(String.format("Affect %d rows.",
					object));
		} else if (object instanceof Boolean) {
			resultItem = createLabelTabItem(String.format("Result %s ", object
					.toString()));
		} else if (object instanceof int[]) {
			// Batch operation result
			StringBuilder builder = new StringBuilder("Batch results");
			builder.append(NEW_LINE);
			int[] results = (int[]) object;
			if (results.length > 0) {
				for (int i : results) {
					builder.append(String.format("Affect %d rows.", i));
					builder.append(NEW_LINE);
				}
			}
			resultItem = createLabelTabItem(builder.toString());
		}

		if (resultItem != null) {
			resultItem.setText("Res");
			folder.setSelection(resultItem);
		}
	}

	private CTabItem createLabelTabItem(String data) {
		CTabItem resultItem = new CTabItem(folder, SWT.NONE);
		Label label = new Label(folder, SWT.WRAP);
		label.setText(data);
		resultItem.setControl(label);
		return resultItem;
	}

	private CTabItem showResultSet(final ResultSet rs) {
		try {
			if (rs == null) {
				// Empty Set.
				return createLabelTabItem("Empty Set");
			} else {
				ResultSetMetaData metaData = rs.getMetaData();
				int columnCount = metaData.getColumnCount();
				Table table = new Table(folder, SWT.V_SCROLL | SWT.H_SCROLL);
				table.setLayoutData(new GridData(GridData.FILL_BOTH));
				table.setHeaderVisible(true);
				table.setLinesVisible(true);
				table.addMouseMoveListener(new MouseMoveListener(){

				    public void mouseMove(
					    MouseEvent paramMouseEvent) {
				    }
				    
				});

				for (int i = 1; i <= columnCount; i++) {
					TableColumn column = new TableColumn(table, SWT.NONE);
					column.setText(metaData.getColumnName(i));
					column.setWidth(100);
				}
				int lines = 0;
				while (rs.next()) {
					TableItem tableItem = new TableItem(table, SWT.NONE);
					for (int i = 1; i <= columnCount; i++) {
						Object rowResult = rs.getObject(i);
						if (rowResult != null) {
							tableItem.setText(i - 1, rowResult.toString());
						} else {
							tableItem.setText(i - 1, "");
						}
					}
					lines++;
					if (lines >= MAX_LINES) {// default just show 100 lines
						break;
					}
				}

				// open a new tab item to show it
				CTabItem resultItem = new CTabItem(folder, SWT.NONE);
				resultItem.setControl(table);
				return resultItem;
			}
		} catch (SQLException e) {
			ExceptionHandler.handle(e);
		}
		return null;
	}
}
